package com.wzcl.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.wzcl.app.dao.model.ActivityGroupPromotion;
import com.wzcl.app.dao.repository.ActivityGroupPromotionRepository;
import com.wzcl.app.model.common.BusinessException;
import com.wzcl.app.model.common.CodeMsg;
import com.wzcl.app.model.common.MyPage;
import com.wzcl.app.model.dto.PromotionDto;
import com.wzcl.app.service.ActivityGroupPromotionService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Log4j2
@Service
@Transactional
public class ActivityGroupPromotionServiceImpl implements ActivityGroupPromotionService {

    @Autowired
    private ActivityGroupPromotionRepository repository;

    @Override
    public ActivityGroupPromotion create(PromotionDto promotionDto) {
        ActivityGroupPromotion promotion = new ActivityGroupPromotion();
        promotion.setActivityId(promotionDto.getActivityId());
        promotion.setGroupSize(promotionDto.getGroupSize());
        promotion.setOrderNo(promotionDto.getOrderNo());
        promotion.setTime(promotionDto.getTime());
        promotion.setValue(new BigDecimal(promotionDto.getValue()));
        return repository.save(promotion);
    }

    @Override
    public ActivityGroupPromotion update(PromotionDto promotionDto) {
        //校验获取
        ActivityGroupPromotion promotion = getAndCheckById(promotionDto);
        //修改
        promotion.setGroupSize(promotionDto.getGroupSize());
        promotion.setOrderNo(promotionDto.getOrderNo());
        promotion.setTime(promotionDto.getTime());
        promotion.setValue(new BigDecimal(promotionDto.getValue()));
        return repository.save(promotion);
    }

    @Override
    public ActivityGroupPromotion getById(Integer promotionId) {
        return repository.findById(promotionId).orElse(null);
    }

    @Override
    public ActivityGroupPromotion deleteById(Integer promotionId) {
        ActivityGroupPromotion promotion = getAndCheckById(promotionId);
        log.info("ActivityGroupPromotion:{} Physical deletion", JSON.toJSONString(promotion));
        repository.delete(promotion);
        return promotion;
    }

    @Override
    public void deleteAllByActivityId(Integer activityId){
        repository.deleteAllByActivityId(activityId);
    }

    @Override
    public void checkValid(PromotionDto promotionDto) {
        if (promotionDto.getGroupSize() == null) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少成团人数");
        }
        if (promotionDto.getTime() == null) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少成团时间");
        }
        if (StringUtils.isBlank(promotionDto.getValue())) {
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL, "缺少价格值");
        }
    }

    @Override
    public void checkConflict(List<ActivityGroupPromotion> promotionList) {
    }

    @Override
    public List<ActivityGroupPromotion> findAllByActivityId(Integer activityId) {
        return repository.findAllByActivityIdOrderByOrderNoDesc(activityId);
    }

    @Override
    public MyPage<ActivityGroupPromotion> findPage(PromotionDto promotionDto) {
        return new MyPage<>(repository.findAll(getSpecification(promotionDto),promotionDto.getPageable()));
    }

    @Override
    public Specification<ActivityGroupPromotion> getSpecification(PromotionDto promotionDto) {
        return new Specification<ActivityGroupPromotion>() {
            @Override
            public Predicate toPredicate(Root<ActivityGroupPromotion> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<Predicate>();
                if (promotionDto.getActivityId() != null) {
                    predicates.add(criteriaBuilder.equal(root.get("activityId"), promotionDto.getActivityId()));
                }
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
    }

    @Override
    public BigDecimal computePrice(BigDecimal currentPrice, List<ActivityGroupPromotion> promotions, Map<String,Object> condition) {
        Integer promotionId = Integer.valueOf(condition.get("PROMOTION_ID")+"");
        ActivityGroupPromotion promotion = getAndCheckById(promotionId);
        return promotion.getValue();
    }

    @Override
    public ActivityGroupPromotion getAndCheckById(Integer id) {
        if (id == null){
            throw new BusinessException(CodeMsg.MUST_BE_NOT_NULL,"缺少拼团Id");
        }
        ActivityGroupPromotion promotion = getById(id);
        if(promotion == null){
            throw new BusinessException(CodeMsg.GROUP_PROMOTION_NOT_EXIST);
        }
        return promotion;
    }

}
